package client.gui.ingame;

import java.awt.BufferCapabilities;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.JWindow;

import client.gui.DisplayAble;

/**
 * Look here for double buffered page flipping (DBPF :D):
 * http://www.exampledepot.com/egs/java.awt/screen_Flip.html
 */
public class Screen extends Thread {
	BufferStrategy strategy = null;
	public JWindow win = null;
	JFrame frame = null;
	DisplayAble display = null;
	boolean run = true;
	JFrame master = null;
	public static Screen instance;

	static {
		instance = new Screen();
	}

	public static Screen getInstance() {
		if (instance == null)
			instance = new Screen();
		return instance;
	}

	public void setDisplay(DisplayAble display) {
		this.display = display;
	}

	public void setMaster(JFrame master) {
		if (master != null) {
			this.master = master;
			master.setFocusable(false);
			master.setVisible(false);
		}
	}

	public Screen() {

		// Determine if page flipping is supported
		GraphicsEnvironment ge = GraphicsEnvironment
				.getLocalGraphicsEnvironment();
		GraphicsDevice gd = ge.getDefaultScreenDevice();
		GraphicsConfiguration gc = gd.getDefaultConfiguration();
		BufferCapabilities bufCap = gc.getBufferCapabilities();
		boolean page = bufCap.isPageFlipping();

		if (page) {
			// Page flipping is supported
		} else {
			// Page flipping is not supported
		}

		// Create a window for full-screen mode
		frame = new JFrame(gd.getDefaultConfiguration());
		win = new JWindow(frame);
		try {
			// Enter full-screen mode
			gd.setFullScreenWindow(win);
			frame.setFocusable(false);
			frame.setVisible(true);
			win.setFocusable(true);
			win.requestFocus();
			win.requestFocusInWindow();
			win.setVisible(true);
			// Create the back buffer
			int numBuffers = 2; // Includes front buffer
			win.createBufferStrategy(numBuffers);
			strategy = win.getBufferStrategy();
			bufCap = strategy.getCapabilities();
			this.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void run() {
		while (run) {
			if (display != null) {
				try {
					win.requestFocus();

					Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
					g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
							RenderingHints.VALUE_ANTIALIAS_ON);

					display.draw(g);
					strategy.show();
					g.dispose();
				} catch (IllegalStateException e) {
				}
			} else {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
		exit();
	}

	public void exit() {
		if (win != null && frame != null) {
			run = false;
			frame.dispose();
			strategy.dispose();
			win.dispose();
		}
		if (master != null) {
			master.setFocusable(true);
			master.setVisible(true);
		}
		GraphicsEnvironment.getLocalGraphicsEnvironment()
				.getDefaultScreenDevice().setFullScreenWindow(null);
		instance = null;
	}

}
